﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Keepo.Models;
using System.Web.Mvc;
using Infrastructure.Data;
using AlbumDesigner.Helpers;

namespace Keepo.Helpers
{
    public class UserHelper
    {
        public static bool IsLogon()
        {
            //check if the user is login or not (has session or not)
            if (HttpContext.Current.Session != null)
            {
                if (HttpContext.Current.Session["user"] != null)
                {
                    return true;
                }
            }
            return false;
        }

        public static User CurrentUser()
        {
            //check if the user is login or not (has session or not)
            if (IsLogon())
            {
                return (HttpContext.Current.Session["user"] as User);
            }
            return null;
        }

        public static bool HasPermission(int userPermissionId)
        {
            //check if the user is login or not (has session or not)
            if (IsLogon())
            {
                if ((HttpContext.Current.Session["user"] as User).UserPermissionId == userPermissionId)
                {
                    return true;
                }
            }
            return false;
        }

        public static bool HasPermission(int[] userPermissionIds)
        {
            //check if the user is login or not (has session or not)
            if (IsLogon())
            {
                if (userPermissionIds.Any(m => m == (HttpContext.Current.Session["user"] as User).UserPermissionId))
                {
                    return true;
                }
            }
            return false;
        }

        static public bool IsEmailRegisteredToUser(string email)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var existUser = repository.First<User>(m => m.Email == email);
                return existUser != null;
            }
        }

        public static int Register(RegisterData registerData)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //create user object
                User user = new User() { Email = registerData.Email, Password = registerData.Password, FirstName = registerData.FirstName, LastName = registerData.LastName, NewsletterSubscription = registerData.NewsletterSubscription };
                user.RegistrationDate = DateTime.Now;
                user.UserPermissionId = 1;
                user.Activate = false;

                //add this user to the DB
                repository.Add<User>(user);
                repository.UnitOfWork.SaveChanges();

                return user.UserId;
            }
        }

        public static void SendActivationEmail(int userId, UrlHelper Url)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var user = repository.GetByKey<User>(userId);
                user.ActivationKey = Guid.NewGuid().ToString();
                string mailBody = String.Format("שלום {0},<br />נרשמת בהצלחה לאתר!<br /><a href='{1}'>הפעל את החשבון שלי באתר</a>", user.FirstName + " " + user.LastName, Url.Action("Activate", "Users", new { key = user.ActivationKey }, "http"));
                MailHelper.SendMail(user.Email, "ברוך הבא ל-Tprint!", mailBody);
                repository.UnitOfWork.SaveChanges();
            }
        }

        public static KeyValuePair<bool, string> RegisterWithEmail(RegisterData registerData, UrlHelper Url)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //there is user with those details
                if (IsEmailRegisteredToUser(registerData.Email))
                {
                    return new KeyValuePair<bool, string>(false, "הדוא\"ל שהוזן כבר רשום לאתר. נסה להירשם עם פרטים אחרים.");
                }

                int userId = Register(registerData);

                SendActivationEmail(userId, Url);

                return new KeyValuePair<bool, string>(true, "נרשמת בהצלחה לאתר!<br />בשניות הקרובות יישלח לך דוא\"ל לצורך הפעלת חשבונך באתר.");
            }
        }

        public static KeyValuePair<bool, string> Login(User user, bool rememberMe, HttpResponseBase Response, HttpSessionStateBase Session)
        {
            //there is user with those details
            if (user == null)
            {
                return new KeyValuePair<bool, string>(false, "User not found!.");
            }

            //if user activated
            if (user.Activate)
            {
                //save the user in Session
                Session["user"] = user;
                Session.Timeout = 60;

                //if the user selected "Remember Me"
                if (rememberMe)
                {
                    Response.Cookies["email"].Value = StringHelper.FromHebrewToGibrish(user.Email);
                    Response.Cookies["password"].Value = StringHelper.FromHebrewToGibrish(StringHelper.Encrypt(user.Password));
                    Response.Cookies["email"].Expires = DateTime.Now.AddDays(2);
                    Response.Cookies["password"].Expires = DateTime.Now.AddDays(2);
                }
                else
                {
                    Response.Cookies["email"].Value = null;
                    Response.Cookies["password"].Value = null;
                }

                try
                {
                    // Login Success
                    CookieGuidAttribute.migrateResourcesFromCookieToUser();
                }
                catch
                {
                    return new KeyValuePair<bool, string>(true, "Connection Ok, Migration Failed!");
                }

                return new KeyValuePair<bool, string>(true, "התחברת בהצלחה לאתר!");
            }
            //if user not activated
            else
            {
                return new KeyValuePair<bool, string>(false, "משתמש זה קיים במאגר אך עדיין לא הופעל.<br />יש להיכנס לדוא\"ל שנשלח מהאתר לכתובת איתה נרשמת ולהפעיל דרכו את החשבון.");
            }

        }

        public static KeyValuePair<bool, string> Login(LoginData loginData, HttpResponseBase Response, HttpSessionStateBase Session)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //search user with this email and password
                var existUser = repository.First<User>(m => m.Email == loginData.Email && m.Password == loginData.Password);

                if (existUser != null)
                {
                    return Login(existUser, loginData.RememberMe, Response, Session);
                }
                //user not found
                else
                {
                    return new KeyValuePair<bool, string>(false, "הדוא\"ל או הסיסמא לא נכונים.<br /><br />אם אתה משתמש חדש - יש להירשם לאתר.<br />אם שכחת סיסמה - שחזר אותה באמצעות שחזור סיסמה.");
                }
            }
        }

        public static KeyValuePair<bool, string> Login(LoginDataWithUsername loginData, HttpResponseBase Response, HttpSessionStateBase Session)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //search user with this username and password
                var existUser = repository.First<User>(m => m.Username == loginData.Username && m.Password == loginData.Password);

                if (existUser != null)
                {
                    return Login(existUser, loginData.RememberMe, Response, Session);
                }
                //user not found
                else
                {
                    return new KeyValuePair<bool, string>(false, "שם המשתמש או הסיסמא לא נכונים.");
                }
            }
        }

        public static KeyValuePair<bool, string> Login(int userId, HttpResponseBase Response, HttpSessionStateBase Session)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //search user with this email and password
                var user = repository.GetByKey<User>(userId);

                if (user != null)
                {
                    return Login(user, false, Response, Session);
                }
                //user not found
                else
                {
                    return new KeyValuePair<bool, string>(false, "UserId Not Found!");
                }
            }
        }

        public static KeyValuePair<bool, string> isRegistrationCodeValid(string code)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var registerationCode = repository.First<RegistrationCode>(m => m.Code == code);

                if (registerationCode == null)
                {
                    return new KeyValuePair<bool, string>(false, "Invalid Registration-Code");
                }

                if (registerationCode.UserId != null)
                {
                    return new KeyValuePair<bool, string>(false, "Registration-Code was already used");
                }

                return new KeyValuePair<bool, string>(true, "Registration-Code is Valid");
            }
        }

        public static void addUserInfo(UserInfo info)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                repository.Add<UserInfo>(info);
                repository.UnitOfWork.SaveChanges();
            }
        }

        public static void InvalidateRegistrationCode(string code, int userId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var registerationCode = repository.First<RegistrationCode>(m => m.Code == code);
                registerationCode.UserId = userId;
                repository.UnitOfWork.SaveChanges();
            }
        }

        public static void Logout(HttpRequestBase Request, HttpResponseBase Response, HttpSessionStateBase Session)
        {
            //clear the cookies of this user
            Request.Cookies.Remove("email");
            Request.Cookies.Remove("password");
            Response.Cookies["email"].Value = null;
            Response.Cookies["password"].Value = null;

            //clear the session of this user
            Session.Remove("user");
            Session["user"] = null;
        }

        public static void ActivateUser(int userId)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                var user = repository.GetByKey<User>(userId);

                user.Activate = true;

                repository.UnitOfWork.SaveChanges();
            }
        }

        public static User ActivateUser(string Key, HttpSessionStateBase Session)
        {
            using (GenericRepository repository = new GenericRepository())
            {
                //find the user to be activated
                var activatedUser = repository.First<User>(m => m.ActivationKey == Key);

                //activate it
                activatedUser.Activate = true;
                repository.UnitOfWork.SaveChanges();

                //login the user (by saving the user in Session)
                Session["user"] = activatedUser;
                Session.Timeout = 60;

                return activatedUser;
            }
        }
    }
}